package org.dromara.sheet.service.impl;

import cn.hutool.json.JSONUtil;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.sheet.domain.SysSheetButton;
import org.dromara.sheet.domain.SysSheetButtonAuth;
import org.dromara.sheet.domain.bo.SysSheetButtonBo;
import org.dromara.sheet.domain.dto.platformList.SearchButtonDto;
import org.dromara.sheet.domain.vo.SysSheetButtonAuthVo;
import org.dromara.sheet.domain.vo.SysSheetButtonVo;
import org.dromara.sheet.enums.YesOrNoEnum;
import org.dromara.sheet.mapper.SysSheetButtonAuthMapper;
import org.dromara.sheet.mapper.SysSheetButtonMapper;
import org.dromara.sheet.service.ISysSheetButtonService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 应用控件Service业务层处理
 *
 * @author Ysl
 * @date 2023-09-01
 */
@RequiredArgsConstructor
@Service
public class SysSheetButtonServiceImpl implements ISysSheetButtonService {

    private final SysSheetButtonMapper baseMapper;
    private final SysSheetButtonAuthMapper buttonAuthMapper;

    /**
     * 查询应用控件
     */
    @Override
    public SysSheetButtonVo queryById(Long sheetFormButtonId){
        return baseMapper.selectVoById(sheetFormButtonId);
    }

    /**
     * 查询应用控件列表
     */
    @Override
    public TableDataInfo<SysSheetButtonVo> queryPageList(SysSheetButtonBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysSheetButton> lqw = buildQueryWrapper(bo);
        Page<SysSheetButtonVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询应用控件列表
     */
    @Override
    public List<SysSheetButtonVo> queryList(SysSheetButtonBo bo) {
        LambdaQueryWrapper<SysSheetButton> lqw = buildQueryWrapper(bo);
        List<SysSheetButtonVo> buttonList = baseMapper.selectVoList(lqw);

        // 查询授予的按钮权限
        if (bo.getRoleId() != null){
            List<SysSheetButtonAuthVo> authList = buttonAuthMapper.selectVoList(
                new LambdaQueryWrapper<SysSheetButtonAuth>().eq(SysSheetButtonAuth::getRoleId, bo.getRoleId())
            );
            buttonList.forEach(button -> {
                authList.forEach(auth -> {
                    if (button.getSheetButtonId().equals(auth.getSheetButtonId())){
                        button.setIsAuth(YesOrNoEnum.YES.getCode());
                    }
                });
            });
        }
        return buttonList;
    }

    private LambdaQueryWrapper<SysSheetButton> buildQueryWrapper(SysSheetButtonBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysSheetButton> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getBindId() != null, SysSheetButton::getBindId, bo.getBindId());
        lqw.eq(bo.getButtonId() != null, SysSheetButton::getButtonId, bo.getButtonId());
        lqw.eq(StringUtils.isNotBlank(bo.getButtonCode()), SysSheetButton::getButtonCode, bo.getButtonCode());
        lqw.like(StringUtils.isNotBlank(bo.getShowName()), SysSheetButton::getShowName, bo.getShowName());
        lqw.eq(StringUtils.isNotBlank(bo.getShowGroup()), SysSheetButton::getShowGroup, bo.getShowGroup());
        lqw.eq(bo.getShowType() != null, SysSheetButton::getShowType, bo.getShowType());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysSheetButton::getStatus, bo.getStatus());
        lqw.eq(bo.getShowArea() != null, SysSheetButton::getShowArea, bo.getShowArea());
        lqw.eq(StringUtils.isNotBlank(bo.getApiUrl()), SysSheetButton::getApiUrl, bo.getApiUrl());
        lqw.eq(StringUtils.isNotBlank(bo.getShowTip()), SysSheetButton::getShowTip, bo.getShowTip());
        lqw.orderByAsc(SysSheetButton::getSort);
        return lqw;
    }

    /**
     * 新增应用控件
     */
    @Override
    public Boolean insertByBo(SysSheetButtonBo bo) {
        SysSheetButton add = MapstructUtils.convert(bo, SysSheetButton.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setSheetButtonId(add.getSheetButtonId());
        }
        return flag;
    }

    /**
     * 修改应用控件
     */
    @Override
    public Boolean updateByBo(SysSheetButtonBo bo) {
        SysSheetButton update = MapstructUtils.convert(bo, SysSheetButton.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysSheetButton entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除应用控件
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 修改或保存应用控件
     *
     * @param list
     * @return
     */
    @Override
    public boolean addOrUpdateSheetButton(List<SysSheetButtonVo> list) {
        // 先获取以保存的数据
        List<SysSheetButton> buttonList = baseMapper.selectList(
            new LambdaQueryWrapper<SysSheetButton>().eq(SysSheetButton::getBindId, list.get(0).getBindId())
        );

        List<SysSheetButtonVo> addListVo = list.stream().filter(item -> item.getSheetButtonId()==null).collect(Collectors.toList());
        List<SysSheetButtonVo> updateListVo = list.stream().filter(item -> item.getSheetButtonId()!=null).collect(Collectors.toList());

        List<SysSheetButton> delList = buttonList.stream().filter(a ->
            !updateListVo.stream().map(SysSheetButtonVo::getSheetButtonId).toList().contains(a.getSheetButtonId())
        ).toList();

        List<SysSheetButton> addList = MapstructUtils.convert(addListVo, SysSheetButton.class);
        List<SysSheetButton> updateList = MapstructUtils.convert(updateListVo, SysSheetButton.class);
        boolean add = true;
        boolean update = true;
        if (addList != null && !addList.isEmpty()) {
            add = baseMapper.insertBatch(addList);
        }
        if (updateList != null && !updateList.isEmpty()) {
            update = baseMapper.updateBatchById(updateList);
        }
        if (!delList.isEmpty()){
            baseMapper.deleteBatchIds(delList.stream().map(SysSheetButton::getSheetButtonId).collect(Collectors.toList()));
        }

        return add && update;
    }

}
